RxJS Observables, Subjects and BehaviorSubjects in Angular

In this tutorial, we shall see about Observable, Subject and BehaviorSubject in angular.

What is an Observable?

Observables are the one that works like publisher and subscriber model. The observable will have an observer to publish any value and those who have subscribed to the observable can be able to get the updated value.

Create an Observable in TimerService

Let's understand this with an example.Create a service using

ng g s timer

Modify the code of service as below

import { Injectable } from '@angular/core';
import { Observable} from 'rxjs';
@Injectable()
export class TimerService {

  private timer = new Observable((observer) => {
    setInterval(() => {
      observer.next(new Date());
    }, 1000);
  });

  constructor() {}
  getTimer() {
    return this.timer;
  }
}

In the above code, we imported the Observable from rxjs package. To create an observable we use the new keyword.

When creating an Observable it takes a callback function with observer as parameter.

This observer will act like a producer which has been set to produce the date for every 1 second and emit it using next function.

The timer observable is declared as private, so that it cannot be accessed directly. If the getTimer() function is called, it will return the timer observable.

Use the Observable in TimerService in AppComponent

Now in app.component.ts file we modify the code as below

import { Component, OnInit } from '@angular/core';
import { TimerService } from './services/timer.service';
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent implements OnInit, OnDestroy {
  timer: Date;
  subscriberObject;
  constructor(private timerService: TimerService) {
  }
  ngOnInit(): void {
    this.subscriberObject = this.timerService.getTimer().subscribe((value: Date) => {
      this.timer = value;
    });
  }

  ngOnDestroy(): void {
    this.subscriberObject.unsubscribe();
  }
}

In app.component.html modify the code as

<p>Time: {{timer}}</p>

In app.component.ts we have implemented the OnInit() and OnDestroy() lifecycle.

In OnInit() life cycle, we will subscribe to the getTimer() function of TimerService which will return an observable. The observable is assigned to the subscriberObject.

In the ngOnDestroy() life cycle event we unsubscribed the subscriterObject using unsubscribe() function.Its always neccessary to unsubscribe any observable that is subscribed.

Now the application will display the time every one second. Remember to check whether the TimerService is registered with the app module.

What are Subject?

As per the definition provided by rxjs. An RxJS Subject is a special type of Observable that allows values to be multicasted to many Observers. While plain Observables are unicast (each subscribed Observer owns an independent execution of the Observable), Subjects are multicast.

Subjects are by default, is an Observable which contains the methods next(), error() and complete(). The next() function is used to emit the latest value.

Creating Subject in TimerService

Let's update our previous example that was created with observable in TimerService to use Subject instead.

import { Injectable } from '@angular/core';
import { Subject} from 'rxjs';
@Injectable({
  providedIn: 'root'
})

export class TimerService {

  private timer = new Subject<Date>();
  constructor() {
    setInterval(() => {
      this.timer.next(new Date());
}, 1000);
  }
  getTimer() {
    return this.timer.asObservable();
  }
}

In the above code, we create a Subject of typeDate and assign to timer variable.

In the constructor of the service we create setInterval to feed the new date to the timer Subject using next() function. The timer Subject can be obtained as observable by calling getTimer() function.

Leave the codes for app.component.ts and app.component.html to be same as done for observable's example.

Now you can see the same output returning the date and time as returned by the observable.

What are BehaviorSubject?

BehaviorSubject is a type of observable that is similar to the Subject but there are few differences. Some of them are

  • It gets the initial value during its declaration.
  • It will always return a value even if no data has been feed.
  • If we subscribe to it, it will immediately return the last emitted value immediately.

Creating BehaviorSubject in TimerService

Let's modify the same program to use BehaviorSubject instead of Subject.

import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
@Injectable({
  providedIn: 'root'
})

export class TimerService {
  private timer = new BehaviorSubject<Date>(new Date());
  constructor() {
    setInterval(() => {
      this.timer.next(new Date());
    }, 1000);
  }
  getTimer() {
    return this.timer.asObservable();
  }
}

Here, instead of importing Subject we imported BehaviorSubject. We create the BehaviorSubject of type Date with initial value of current date.

Leave the codes for app.component.ts and app.component.html to remain the same.

Now you can notice that when the app loads, it will load with the initial date and time. This behaviour is because the BehaviorSubject will immediately emit the date value.


Most Read